package cn.lx.es.query.config;

import cn.lx.es.query.index.EsIndexMangerService;
import cn.lx.es.query.listener.CreateIndexListener;
import cn.lx.es.query.processor.SearchAnnotationProcessor;
import cn.lx.es.query.processor.*;
import cn.lx.es.query.registrar.SearchProcessorRegistrar;
import cn.lx.es.query.search.service.ElasticsearchTemplate;
import cn.lx.es.query.search.service.EsSearchService;
import cn.lx.es.query.search.service.impl.ElasticsearchTemplateImpl;
import cn.lx.es.query.search.service.impl.EsSearchServiceImpl;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

import java.util.ArrayList;
import java.util.List;

/**
 * @author wcy
 * @version 1.0
 * @description: Es动态查询自动配置
 * @date 2025-07-02 下午12:02
 */
@Configuration
@ConditionalOnClass(ElasticsearchTemplate.class)
@EnableConfigurationProperties(DynamicEsQueryAutoProperties.class)
public class DynamicEsQueryAutoConfig {

    private static final Logger logger = LoggerFactory.getLogger(DynamicEsQueryAutoConfig.class);

    @Bean(destroyMethod = "close")
    public RestHighLevelClient esRestClient(DynamicEsQueryAutoProperties esQueryAutoProperties) {
        String esHosts = esQueryAutoProperties.getEsHosts();
        logger.info("esHosts={}", esHosts);
        String[] hosts = esHosts.split(",");
        List<HttpHost> httpHostList = new ArrayList<>();
        for (String host : hosts){
            httpHostList.add(HttpHost.create(host));
        }
        HttpHost[] httpHosts = httpHostList.toArray(new HttpHost[0]);
        RestClientBuilder restClientBuilder = RestClient.builder(httpHosts);

        restClientBuilder.setRequestConfigCallback(req -> {
            req.setConnectionRequestTimeout(esQueryAutoProperties.getEsReqTimeout());
            // 与服务器建立连接的超时时间
            req.setConnectTimeout(esQueryAutoProperties.getEsConnectTimeout());
            // 网络通讯的超时时间
            req.setSocketTimeout(esQueryAutoProperties.getEsSocketTimeout());
            return req;
        });

        RestHighLevelClient restHighLevelClient = new RestHighLevelClient(restClientBuilder);
        return restHighLevelClient;
    }

    @Bean
    public EsIndexMangerService indexMangerService(RestHighLevelClient restHighLevelClient) {
        return new EsIndexMangerService(restHighLevelClient);
    }

    @Bean
    public CreateIndexListener createIndexListener(EsIndexMangerService esIndexMangerService) {
        return new CreateIndexListener(esIndexMangerService);
    }


    /**
     * 注册ES搜索服务
     * 处理器通过Spring的自动发现机制自动注入
     */
    @Bean
    @ConditionalOnMissingBean
    public EsSearchService esSearchService(List<SearchAnnotationProcessor> processors) {
        return new EsSearchServiceImpl(processors);
    }

    @Bean
    public ElasticsearchTemplate elasticsearchTemplate(RestHighLevelClient restHighLevelClient) {
        return new ElasticsearchTemplateImpl(restHighLevelClient);
    }
}
